{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<br>\n",
    "<center><font face=\"黑体\" size=4>《机器学习基础实践》课程实验指导书</font></center>\n",
    "<br>\n",
    "<br>\n",
    "<center><font face=\"黑体\",size=4>第4章 支持向量机模型</font></center>\n",
    "\n",
    "\n",
    "$\\textbf{1.实验目标}$\n",
    "\n",
    "通过本章内容的学习，可以掌握最大间隔、支持向量、对偶问题求解、核函数等机器学习领域的重要知识，并且能够动手实现一个简单的支持向量机分类模型。\n",
    "\n",
    "$\\textbf{2.实验内容}$\n",
    "\n",
    "$\\textbf{4.1 支持向量机的基本原理}$\n",
    "\n",
    "对于二分类问题，给定训练数据集$D=\\{(\\textbf{x}_1,y_1),(\\textbf{x}_2,y_2),…, (\\textbf{x}_m,y_m)\\}，y_i\\in\\{-1, +1\\}$，学习算法的最基本的思想就是基于训练集$D$在样本空间中找到一个划分超平面，将两个不同的类别分开。划分超平面可以通过如式(4.1)所示的线性方程来描述，其中$\\textbf{w}=[w_1,w_2,…,w_d]$是划分超平面的法向量，决定了划分超平面的方向；$b$为位移项，决定了超平面与原点之间的距离。从训练数据集$D$中学习得到参数$\\textbf{w}$和$b$后，就可以确定划分超平面。\n",
    "\n",
    "\\begin{equation}\n",
    "f(\\textbf{x})= \\textbf{w}^T\\textbf{x}+b, \\  式(4.1)\n",
    "\\end{equation}\n",
    "                                                    \n",
    "在实际任务中，通常可以找到多划分超平面，可以将不同类别的训练数据分开，如下图所示。不同的划分超平面对训练样本的局部扰动的鲁棒性不一样，对未见样本的泛化能力也存在着很大的区别。机器学习的目的就是从训练集中学习得到泛化能力更强，鲁棒性更好的模型，即要求学习得到的划分超平面，能够对噪声数据具有较高的抗干扰能力。\n",
    "\n",
    "<img src=picture/svm1.png>\n",
    "\n",
    "\n",
    "假设超平面$(\\textbf{w},b)$能够将训练集样本都分类正确，即对于任意样本$(\\textbf{x}_i,y_i)\\in D$，模型的输出满足式(4.2)所示的条件，式中使得等号成立的训练样本被称为支持向量，而两个不同类别支持向量到划分超平面的距离之和被称为间隔，如式(4.3)所示。\n",
    "\n",
    "\\begin{equation}\n",
    "\\begin{cases}\n",
    "\\textbf{w}^{T}\\textbf{x}_i\\ge +1 , & if \\ y_i = +1\n",
    "\\cr \\textbf{w}^{T}\\textbf{x}_i\\le -1 , & if \\ y_i = -1\n",
    "\\end{cases}\n",
    " \\  式(4.2)\n",
    "\\end{equation}\n",
    "\n",
    "\\begin{equation}\n",
    "\\gamma = \\frac{2}{\\Vert \\textbf{w}\\Vert} \\  式(4.3)\n",
    "\\end{equation}\n",
    "\n",
    "支持向量与间隔的示意图如下图所示。从图中可以看出，要使得划分超平面的鲁棒性高，就需要不同类别的支持向量到划分超平面的距离之和最大，即具有最大间隔的划分超平面。支持向量机模型的基本思想就是找到具有最大间隔的划分超平面，支持向量机模型的求解等价于求解如式(4.4)所示的目标函数，即寻找一个超平面$(\\textbf{w},b)$使得间隔最大，且能将训练数据集中的所有样本都分类正确。对式(4.4)的求解等价于最小化如式(4.5)所示的函数。\n",
    "\n",
    "<img src=picture/svm2.png>\n",
    "\n",
    "\\begin{equation}\n",
    "\\underset{\\textbf{w},b} \\max \\frac{2}{\\Vert \\textbf{w}\\Vert} \\\\\n",
    "s.t. y_i(\\textbf{w}^{T}\\textbf{x}_{i}+b) \\ge 1, i=1,2,...,m   \\ 式(4.4)\n",
    "\\end{equation}\n",
    "\n",
    "\n",
    "\\begin{equation}\n",
    "\\underset{\\textbf{w},b} \\min \\frac{1}{2}\\Vert \\textbf{w}\\Vert^2 \\\\\n",
    "s.t. y_i(\\textbf{w}^{T}\\textbf{x}_{i}+b) \\ge 1, i=1,2,...,m   \\ 式(4.5)\n",
    "\\end{equation}\n",
    "\n",
    "式(4.5)的约束条件要求每个训练样本都被分类正确，在实际任务中，这样的要求有可能造成模型的过拟合。为此，可以允许某些样本分类错误，即存在部分样本不满足式(4.5)的约束条件。软间隔支持向量机就是在最大化间隔的同时，允许少量的样本不满足约束条件，以提高支持向量机模型的鲁棒性。于是，式(4.5)所示的优化目标可以表示为，   \n",
    "\n",
    "\n",
    "\\begin{equation}\n",
    "\\underset{\\textbf{w},b} \\min \\frac{1}{2}\\Vert \\textbf{w}\\Vert^2 +C\\sum_{i=1}^{m}\\xi_{i},\\\\\n",
    "s.t. y_i(\\textbf{w}^{T}\\textbf{x}_{i}+b) \\ge 1-\\xi_{i}, \\\\\n",
    "\\xi_{i} \\ge 0, i=1,2,...,m   \\  式(4.6)\n",
    "\\end{equation}\n",
    "\n",
    "其中$\\xi_{i}$是一个松弛变量，表示允许样本的预测值与真实值存在一定的误差。\n",
    "\n",
    "$\\textbf{4.2 支持向量机模型的求解}$\n",
    "\n",
    "支持向量机模型的求解实际上就是寻找参数$\\textbf{w}$和$b$，使得式(4.6)所示的目标函数最小。可以看出，式(4.6)是带有不等式约束的多元函数求极值问题，这类问题可以通过拉格朗日乘数法解决。\n",
    "\n",
    "使用拉格朗日乘数法可以将式(4.6)所示的最小值问题转化为如式(4.7)所示的拉格朗日函数，其中$\\boldsymbol{\\alpha}=[\\alpha_{1},\\alpha_{2},...\\alpha_{m}]$,$\\boldsymbol{\\mu}=[\\,u{1},\\mu{2},...\\mu{m}]$都是由$m$个拉格朗日乘整数组成的向量。 \n",
    "\n",
    "<img src=picture/svm3.png>式(4.7)\n",
    "\n",
    "\n",
    "其中，$\\alpha_{i} \\ge 0,\\mu_{i} \\ge 0$都是拉格朗日乘子。令$L(\\textbf{w},b,\\boldsymbol{\\alpha},\\boldsymbol{\\mu})$对$\\textbf{w}$和$b$的偏导数等于零，可得\n",
    "\n",
    "<img src=picture/svm4.png>式(4.8)\n",
    "\n",
    "将式(4.8)带入式(4.7)，消去$\\textbf{w}$和$b$后，可得\n",
    "\n",
    "<img src=picture/svm5.png> 式(4.9)\n",
    "\n",
    "式(4.9)所示的是式(4.6)的对偶问题，通过求解式(4.9)得到向量之后，支持向量机模型就可以表示为\n",
    "\n",
    "<img src=picture/svm6.png> 式(4.10)\n",
    "\n",
    "由于式(4.9)中的存在不等式约束条件，求解式(4.9)时还需要满足如式(4.11)所示的KKT条件。\n",
    "\n",
    "<img src=picture/svm7.png> 式(4.11)\n",
    " \n",
    "根据式(4.11)，对任意训练样本$(\\textbf{x}_i,y_i)$，总有$\\alpha_{i}=0$或者$y_if(\\textbf{x}_i)=1-\\xi_{i}$，若$\\alpha_{i}=0$，则该样本不会再式(4.10)中出现，对最终的支持向量机模型没有任何影响；若$\\alpha_{i}>0$则必有$y_if(\\textbf{x}_i)=1-\\xi_{i}$，所对应的样本点位于最大间隔的边界上，是一个支持向量。支持向量机模型训练完成后，大部分的训练样本都不需要保存，支持向量机模型只与支持向量有关。\n",
    "\n",
    "$\\textbf{4.3 序列最小值优化算法}$\n",
    "\n",
    "上一节讲到，支持向量机模型的求解是将如式(4.6)所示的目标函数的求解转化为如式(4.8)所示的对偶问题的求解，对于式(4.8)所示的函数优化问题，由$m$个变量组成的向量$\\boldsymbol{\\alpha}$需要在目标函数极小化的时候求出。由于变量的个数很多，式(4.8)的形式比较复杂，直接优化求解非常困难。序列最小值优化算法(Sequential Minimal Optimization, 简称SMO) 采用了一种启发式的方法。它每次只优化两个变量，将其他的变量都视为常数。这样SMO算法将一个复杂的优化算法转化为一个比较简单的两变量优化问题。假设一次优化过程中，我们只考虑变量$\\alpha_1$和$\\alpha_2$，而固定其他参数，则式(4.8)可以表示为\n",
    "\n",
    "<img src=picture/svm8.png>式(4.12)\n",
    "\n",
    "由于总有$y_{i}^{2}=1$，且$\\alpha_{1}y_1+\\alpha_{2}y_2=\\xi$，可得$\\alpha_{1}=y_1(\\xi-\\alpha_{2}y_{2})$，带入式(4.12)，可以将包含两个变量的优化问题，转化为只包含一个变量$\\alpha_{2}$的优化问题\n",
    "\n",
    "<img src=picture/svm9.png>(4.13)\n",
    "\n",
    "上式对变量$\\alpha_{2}$求导数，并令导数等于零，可得\n",
    "\n",
    "<img src=picture/svm10.png>(4.14)\n",
    "\n",
    "将$\\alpha_{1}y_1+\\alpha_{2}y_2=\\xi$带入式(4.14)，就可以更新变量$\\alpha_{2}$的值，如下所示\n",
    "\n",
    "<img src=picture/svm11.png> (4.15)\n",
    "\n",
    "在更新优化两个变量$\\alpha_{1}$和$\\alpha_{2}$之后，如果，0＜$\\alpha_{1}$＜C 则有\n",
    "\n",
    "<img src=picture/svm12.png>(4.16)\n",
    "\n",
    "于是新的常数项$b$可以表示为\n",
    "\n",
    "<img src=picture/svm13.png>(4.17)\n",
    "\n",
    "同样，如果，0＜$\\alpha_{2}$＜C 则有\n",
    "\n",
    "<img src=picture/svm14.png>(4.18)\n",
    "\n",
    "<img src=picture/svm15.png>(4.19)\n",
    "\n",
    "于是常数项b的值可以更新为\n",
    "\n",
    "<img src=picture/svm16.png> (4.20)\n",
    "\n",
    "$\\textbf{4.4 支持向量机模型的实现}$\n",
    "\n",
    "\n",
    "本节通过使用Python编程语言，实现SupportVectorMachine类来封装一个简单的支持向量机模型的实现，代码如下所示。\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "\n",
    "\"\"\"\n",
    "SupportVectorMachine类封装了支持向量机分类模型的实现框架\n",
    "\"\"\"\n",
    "import random\n",
    "import numpy as np\n",
    "class SupportVectorMachine:\n",
    "    #构造函数\n",
    "    def __init__(self, x_train,y_train,C,toler,max_iter):\n",
    "        \"\"\"\n",
    "        输入参数 x_train:训练集的特征矩阵\n",
    "        输入参数 y_train:训练集的类别矩阵\n",
    "        输入参数 C: 正则常数，C>0\n",
    "        输入参数 toler: 允许的预测误差\n",
    "        输入参数 max_iter: 最大迭代次数\n",
    "        \"\"\"\n",
    "        self.x_train = np.mat(x_train)\n",
    "        self.y_train = np.mat(y_train)\n",
    "        self.C = C\n",
    "        self.toler = toler\n",
    "        self.max_iter = max_iter\n",
    "        m,n = np.shape(self.x_train)\n",
    "        self.alphas = np.zeros((m,1)) \n",
    "        self.b = 0\n",
    "    #从m个对偶因子中随机选择一个与alpha_i不同的对偶因子alpha_j\n",
    "    def rand_select_j(self,i, m):\n",
    "        \"\"\"\n",
    "        输入参数 i:已经选择的第一个对偶因子alpha_i的编号\n",
    "        输出参数 m:对偶因子的总数\n",
    "        输出结果 j: 选择的第二个对偶因子alpha_j的编号\n",
    "        \"\"\"\n",
    "        j = i\n",
    "        while(j==i):\n",
    "            j = int(random.uniform(0,m))\n",
    "        return j\n",
    "    #根据对偶因子的上限和下限，修剪对偶因子\n",
    "    def clip_alpha(self, aj, H, L):\n",
    "        \"\"\"\n",
    "        输入参数 aj:对偶因子alpha_j\n",
    "        输出参数 H:对偶因子的上限\n",
    "        输出参数 L:对偶因子的下限\n",
    "        输出结果 aj: 修剪后的对偶因子alpha_j\n",
    "        \"\"\"\n",
    "        if aj > H:\n",
    "            aj = H\n",
    "        if L > aj:\n",
    "            aj = L\n",
    "        return aj\n",
    "    #SMO算法求解\n",
    "    def smo(self):\n",
    "        iters = 0\n",
    "        #m表示训练样本的个数\n",
    "        m,n = np.shape(self.x_train)\n",
    "        while iters < self.max_iter:\n",
    "            alpha_pairs_changed = 0            \n",
    "            for  i in range(m):    \n",
    "                #选取第一个对偶因子alpha_i\n",
    "                #计算当前迭代的模型法向量W_i,如式(5.8)所示\n",
    "                W_i = np.dot(np.multiply(self.alphas, self.y_train).T, self.x_train) \n",
    "                #计算模型对样本x_i的预测输出\n",
    "                f_x_i = float(np.dot(W_i, self.x_train[i,:].T)) + self.b   \n",
    "                #计算模型对样本x_i的预测误差\n",
    "                E_i = f_x_i - float(self.y_train[i])    \n",
    "                if((self.y_train[i]*E_i < -self.toler) and  (self.alphas[i] < self.C)) or \\\n",
    "                    ((self.y_train[i]*E_i > self.toler) and (self.alphas[i] > 0)):  \n",
    "                        #选取另一个不相同的对偶因子alpha_j\n",
    "                        j = self.rand_select_j(i, m) \n",
    "                        #计算当前迭代的模型法向量W_i,如式(5.8)所示\n",
    "                        W_j = np.dot(np.multiply(self.alphas, self.y_train).T, self.x_train)\n",
    "                        #计算模型对样本x_j的预测输出\n",
    "                        f_x_j = float(np.dot(W_j, self.x_train[j,:].T)) + self.b    \n",
    "                        #计算模型对样本x_j的预测误差\n",
    "                        E_j = f_x_j - float(self.y_train[j])    \n",
    "                        #保存旧的对偶因子 alpha_i和alpha_j\n",
    "                        alpha_iold = self.alphas[i].copy()\n",
    "                        alpha_jold = self.alphas[j].copy()\n",
    "                        #设置对偶因子的上界和下界\n",
    "                        if (self.y_train[i] != self.y_train[j]):  \n",
    "                            L = max(0, self.alphas[j] - self.alphas[i])  \n",
    "                            H = min(self.C, self.C + self.alphas[j] - self.alphas[i])\n",
    "                        else:                              \n",
    "                            L = max(0, self.alphas[j] + self.alphas[i] - self.C)\n",
    "                            H = min(self.C, self.alphas[j] + self.alphas[i])\n",
    "                        if H == L :continue\n",
    "                        #计算对偶因子alpha_j的更新值，如式(5.15)所示\n",
    "                        #计算式(5.15)的分母部分\n",
    "                        eta = 2.0 * self.x_train[i,:]*self.x_train[j,:].T - self.x_train[i,:]*self.x_train[i,:].T - \\\n",
    "                            self.x_train[j,:]*self.x_train[j,:].T\n",
    "                        if eta >= 0: continue\n",
    "                        #根据式(5.15)更新alpha_j\n",
    "                        self.alphas[j] = (self.alphas[j] - self.y_train[j]*(E_i - E_j))/eta\n",
    "                        #对alpha_j按照上界和下界进行修剪\n",
    "                        self.alphas[j] = self.clip_alpha(self.alphas[j], H, L)   \n",
    "                        if (abs(self.alphas[j] - alpha_jold) < 0.00001):\n",
    "                            continue\n",
    "                        #根据alpha_j的更新值，更新alpha_i\n",
    "                        self.alphas[i] = self.alphas[i] + self.y_train[j]*self.y_train[i]*(alpha_jold - self.alphas[j])\n",
    "                        #更新两个对偶因子后，跟新常数项b\n",
    "                        b1 = self.b - E_i + self.y_train[i]*(alpha_iold - self.alphas[i])*np.dot(self.x_train[i,:], self.x_train[i,:].T) +\\\n",
    "                            self.y_train[j]*(alpha_jold - self.alphas[j])*np.dot(self.x_train[i,:], self.x_train[j,:].T)\n",
    "                        b2 = self.b - E_j + self.y_train[i]*(alpha_iold - self.alphas[i])*np.dot(self.x_train[i,:], self.x_train[j,:].T) +\\\n",
    "                            self.y_train[j]*(alpha_jold - self.alphas[j])*np.dot(self.x_train[j,:], self.x_train[j,:].T)\n",
    "                        if (0 < self.alphas[i]) and (self.C > self.alphas[i]):\n",
    "                            self.b = b1\n",
    "                        elif (0 < self.alphas[j]) and (self.C > self.alphas[j]):\n",
    "                            self.b = b2\n",
    "                        else:\n",
    "                            self.b = (b1 + b2)/2.0\n",
    "                        alpha_pairs_changed += 1#完成一对对偶因子的更新\n",
    "                if (alpha_pairs_changed == 0):#若果没有更新，则进入下一次迭代\n",
    "                    iters += 1\n",
    "                else: \n",
    "                    iters = 0\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "2. 生成一个二分类数据集，验证实现方法的正确性"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 720x360 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 720x360 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "\n",
    "if __name__ ==\"__main__\":\n",
    "    import matplotlib.pyplot as plt\n",
    "    from sklearn.datasets import make_blobs\n",
    "    import pandas as pd \n",
    "    #生成一个包含200个样本,每个样本有2维特征的二分类数据集\n",
    "    data, label = make_blobs(n_samples=200, n_features=2, centers=2)\n",
    "    for i in range(len(label)):\n",
    "        if label[i]==0:\n",
    "            label[i]=-1\n",
    "    df = pd.DataFrame()\n",
    "    df['x1']=data[:,0]\n",
    "    df['x2']=data[:,1]\n",
    "    df['class']=label\n",
    "    #绘制训练数据\n",
    "    positive = df[df[\"class\"] == 1]\n",
    "    negative = df[df[\"class\"] == -1]\n",
    "    fig, ax = plt.subplots(figsize=(10,5))\n",
    "    ax.scatter(positive[\"x1\"], positive[\"x2\"], s=30, c=\"b\", marker=\"o\", label=\"class 1\")\n",
    "    ax.scatter(negative[\"x1\"], negative[\"x2\"], s=30, c=\"r\", marker=\"x\", label=\"class -1\")\n",
    "    ax.legend()\n",
    "    ax.set_xlabel(\"x1\")\n",
    "    ax.set_ylabel(\"x2\")\n",
    "    #获取训练数据的特征矩阵和标签矩阵\n",
    "    orig_data = df.values   \n",
    "    cols = orig_data.shape[1]\n",
    "    data_mat = orig_data[:,0:cols-1]\n",
    "    label_mat = orig_data[:,cols-1:cols]\n",
    "    #训练支持向量及模型\n",
    "    model = SupportVectorMachine(data_mat, label_mat,0.6, 0.001, 100)\n",
    "    model.smo()    \n",
    "    #可视化支持向量、划分超平面\n",
    "    support_x = []\n",
    "    support_y = []\n",
    "    class1_x = []\n",
    "    class1_y = []\n",
    "    class01_x = []\n",
    "    class01_y = []\n",
    "    for i in range(200):\n",
    "        if model.alphas[i] > 0.0:\n",
    "            support_x.append(data_mat[i,0])\n",
    "            support_y.append(data_mat[i,1])        \n",
    "    for i in range(200):\n",
    "        if label_mat[i] == 1:\n",
    "            class1_x.append(data_mat[i,0])\n",
    "            class1_y.append(data_mat[i,1])\n",
    "        else:\n",
    "            class01_x.append(data_mat[i,0])\n",
    "            class01_y.append(data_mat[i,1])       \n",
    "    w_best = np.dot(np.multiply(model.alphas, label_mat).T, data_mat)\n",
    "    fig, ax = plt.subplots(figsize=(10,5))\n",
    "    ax.scatter(support_x, support_y, s=100, c=\"y\", marker=\"v\", label=\"support_v\")\n",
    "    ax.scatter(class1_x, class1_y, s=30, c=\"b\", marker=\"o\", label=\"class 1\")\n",
    "    ax.scatter(class01_x, class01_y, s=30, c=\"r\", marker=\"x\", label=\"class -1\")\n",
    "    a = min(data_mat[:,0])\n",
    "    b = max(data_mat[:,0])\n",
    "    lin_x = np.linspace(a,b,200)\n",
    "    lin_y = (-float(model.b) - w_best[0,0]*lin_x) / w_best[0,1]\n",
    "    plt.plot(lin_x, lin_y, color=\"green\") \n",
    "    ax.legend()\n",
    "    ax.set_xlabel(\"x1\")\n",
    "    ax.set_ylabel(\"x2\")\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "$\\textbf{4.5 实践任务}$\n",
    "\n",
    "\n",
    "1. 查阅核函数相关资料，在本章实现的SupportVectorMachine类的基础上，编程实现带核函数的支持向量机模型，并创建一个线性不可分的数据集，验证实现的支持向量机模型的正确性。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "#添加代码，完成实践任务"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
